﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Linq.Expressions;
using SmartLib.Reflection.Dynamic;
using System.ComponentModel;

namespace SmartLib.Reflection
{
    internal class PropertyReflection
    {
        private DynamicProperty.SetValueExecutor _setValueExecutor;
        private DynamicProperty.GetValueExecutor _getValueExecutor;
        private string _columnName;
        private bool _ignoreUpdate;
        private bool _ignoreInsert;
        private bool _ignoreSelect;
        private TypeConverter _converter;


        public string ColumnName { get { return _columnName; } }
        public bool IgnoreUpdate { get { return _ignoreUpdate; } }
        public bool IgnoreInsert { get { return _ignoreInsert; } }
        public bool IgnoreSelect { get { return _ignoreSelect; } }

        public PropertyInfo _property;

        /// <summary>
        /// 构造PropertyReflection
        /// </summary>
        /// <param name="property">PropertyInfo</param>
        public PropertyReflection(PropertyInfo property)
        {
            Utils.AssertUtils.IsNotNull(property, "property 不能为空");
            _property = property;

            _setValueExecutor = Dynamic.DynamicProperty.CompileSetValueExecutor(_property);
            _getValueExecutor = Dynamic.DynamicProperty.CompileGetValueExecutor(_property);
            _converter = TypeDescriptor.GetConverter(_property.PropertyType);

            InitAttribute();
        }

        /// <summary>
        /// 获取属性值，如果当前属性不允许读取返回null
        /// </summary>
        /// <param name="instance">实例对象，如果属性是静态的instance可以传null</param>
        /// <returns></returns>
        public Object GetValue(object instance)
        {
            if (_getValueExecutor == null) return null;
            return _getValueExecutor(instance);
        }

        /// <summary>
        /// 设置属性值，如果当前属性不允许写入，则直接返回
        /// </summary>
        /// <param name="instance">实例对象，如果属性是静态的instance可以传null</param>
        /// <param name="value">属性值</param>
        public void SetValue(object instance, object value)
        {
            if (_setValueExecutor == null) return;

            Type desType = value.GetType();
            if (desType == _property.PropertyType || _property.PropertyType.IsInstanceOfType(desType))
            {
                _setValueExecutor(instance, value);
            }
            else if (_converter.CanConvertTo(_property.PropertyType))
            {
                _setValueExecutor(instance, _converter.ConvertTo(value, _property.PropertyType));
            }
        }

        /// <summary>
        /// 初始化特殊
        /// </summary>
        private void InitAttribute()
        {
            object[] attrs = _property.GetCustomAttributes(true) as object[];

            if (attrs != null)
            {
                foreach (var attr in attrs)
                {
                    if (attr is Attributes.TableColumnAttribute)
                    {
                        _columnName = ((Attributes.TableColumnAttribute)attr).ColumnName;
                        _ignoreInsert = ((Attributes.TableColumnAttribute)attr).IgnoreInsert;
                        _ignoreSelect = ((Attributes.TableColumnAttribute)attr).IgnoreSelect;
                        _ignoreUpdate = ((Attributes.TableColumnAttribute)attr).IgnoreUpdate;
                    }
                }
            }

            if (string.IsNullOrEmpty(_columnName)) _columnName = _property.Name;
        }
    }
}
